package com.huiying.service.Impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.huiying.constant.MessageConstant;
import com.huiying.context.BaseContext;
import com.huiying.entity.dto.WorkDTO;
import com.huiying.entity.dto.WorkPageQueryDTO;
import com.huiying.entity.entity.*;
import com.huiying.entity.result.PageResult;
import com.huiying.entity.vo.UserVO;
import com.huiying.entity.vo.WorkPageVO;
import com.huiying.entity.vo.WorkVO;
import com.huiying.mapper.*;
import com.huiying.service.CommonService;
import com.huiying.service.WorkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author: lsh
 * @Date: 2024/12/03/21:37
 * @Description: 作品服务实现类
 */
@Service
@Slf4j
public class WorkServiceImpl implements WorkService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WorkMapper workMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private ContentMapper contentMapper;

    @Autowired
    private ImageMapper imageMapper;

    @Autowired
    private ReadMapper readMapper;

    @Autowired
    private FollowMapper followMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private FavoriteMapper favoriteMapper;

    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    private static final String WORK = "1";

    /**
     * 新增作品
     * @param workDTO 作品数据传输对象
     * @return: void
     */
    @Override
    @Transactional
    public void addWork(WorkDTO workDTO) {
        Long userId = BaseContext.getCurrentId();
        log.info("{}",userId);

        UserVO user = userMapper.getById(userId);

        // 判断用户是否已经实名认证
        String isAuthenticated = user.getName() != null && user.getIdNumber() != null ? "1" : "0";

        // 创建作品对象，复制DTO中的内容
        Work work = new Work();
        BeanUtils.copyProperties(workDTO,work);
        work.setUserId(userId);
        work.setUsername(user.getUsername());
        work.setIsAuthenticated(isAuthenticated);

        // 在数据库中插入新的作品
        workMapper.insert(work);
        Long workId = work.getId();  // 获取插入后的作品ID

        // 获取标签列表，去重后插入内容标签关系表
        List<ContentTag> contentTags = getContentTags(workDTO, workId);

        // 批量插入标签数据
        if (!contentTags.isEmpty()) {
            contentMapper.addContentTags(contentTags);
        }

        // 将作品的图片插入图片表
        List<Image> imageList = getImages(workDTO, workId);

        // 批量插入图片数据
        if (!imageList.isEmpty()) {
            imageMapper.addContentImages(imageList);
        }
    }

    /**
     * 根据id查询作品
     * @param workId 作品id
     * @return: com.fx.vo.WorkVO
     */
    @Override
    public WorkVO getById(Long workId) {
        Long userId = BaseContext.getCurrentId();

        //添加阅读记录
        Read read = Read.builder()
                .userId(userId)
                .itemType(WORK)
                .itemId(workId)
                .readTime(LocalDateTime.now())
                .build();
        readMapper.insert(read);

        WorkVO workVO = workMapper.getWorkInfoById(workId,userId);

        //查询用户是否已经互相关注
        String isFollow = "0";
        if (userId.equals(workVO.getUserId())){
            isFollow = "2";
        }else {
            Follow follow = followMapper.getFollowByUserId(userId,workVO.getUserId());
            if (follow != null){
                isFollow = "1";
            }
        }

        //获取点赞数
        long likes = commonService.countLikes(workId,WORK);
        log.info("点赞数{}",likes);

        workVO.setLikeCount(likes);
        workVO.setIsFollow(isFollow);

        return workVO;
    }

    /**
     *
     * @param workDTO 作品数据传输对象
     * @param id 作品id
     * @return: java.util.List<com.fx.entity.ContentTag>
     */
    private static List<ContentTag> getContentTags(WorkDTO workDTO, Long id) {
        List<Tag> tags = workDTO.getTags();
        List<ContentTag> contentTags = new ArrayList<>();
        Set<Long> existingTagIds = new HashSet<>();  // 用 Set 来去重

        tags.forEach(tag -> {
            if (!existingTagIds.contains(tag.getId())) {
                existingTagIds.add(tag.getId());
                ContentTag contentTag = new ContentTag();
                contentTag.setTagId(tag.getId());
                contentTag.setContentId(id);
                contentTag.setContentType(WORK);
                contentTag.setCreateTime(LocalDateTime.now());
                contentTags.add(contentTag);
            }
        });
        return contentTags;
    }

    /**
     * 获取标签列表并去重
     * @param workDTO
     * @param id
     * @return: java.util.List<com.fx.entity.Image>
     */
    private static List<Image> getImages(WorkDTO workDTO, Long id) {
        List<String> images = workDTO.getImages();
        List<Image> imageList = new ArrayList<>();
        Set<String> existingImageUrls = new HashSet<>(); // 用 Set 来避免重复插入相同的图片

        images.forEach(imageUrl -> {
            if (!existingImageUrls.contains(imageUrl)) {
                existingImageUrls.add(imageUrl);
                Image image = new Image();
                image.setImageURL(imageUrl);
                image.setWorkId(id);
                image.setCreateTime(LocalDateTime.now());
                imageList.add(image);
            }
        });
        return imageList;
    }

    /**
     * 作品分页查询
     * @param workPageQueryDTO 作品分页查询数据传输对象
     * @return: com.fx.result.Result<com.fx.result.PageResult>
     */
    @Override
    public PageResult pageQuery(WorkPageQueryDTO workPageQueryDTO) {
        PageHelper.startPage(workPageQueryDTO.getPage(), workPageQueryDTO.getPageSize());

        Page<WorkPageVO> page = workMapper.pageQuery(workPageQueryDTO);

        long total = page.getTotal();
        List<WorkPageVO> result = page.getResult();

        return new PageResult(total,result);
    }

    /**
     * 修改需求单
     * @param workDTO 作品数据传输对象
     * @return: void
     */
    @Override
    @Transactional
    public void updateWork(WorkDTO workDTO) {
        //删除原有标签记录
        tagMapper.deleteByContentId(workDTO.getId(),WORK);
        //删除原有图片
        imageMapper.deleteByWorkId(workDTO.getId());

        //更新需求单基本信息
        workMapper.updateWork(workDTO);

        List<ContentTag> contentTags = new ArrayList<>();
        List<Image> images = new ArrayList<>();

        // 3. 插入新的标签和图片
        if (workDTO.getTags() != null && !workDTO.getTags().isEmpty()) {
            workDTO.getTags().forEach(tag -> {
                ContentTag contentTag = ContentTag.builder()
                        .contentId(workDTO.getId())
                        .contentType(WORK)
                        .tagId(tag.getId())
                        .createTime(LocalDateTime.now())
                        .build();
                contentTags.add(contentTag);
            });
            contentMapper.addContentTags(contentTags);
        }

        if (workDTO.getImages() != null && !workDTO.getImages().isEmpty()) {
            workDTO.getImages().forEach(image->{
                Image image1 = Image.builder()
                        .workId(workDTO.getId())
                        .imageURL(image)
                        .createTime(LocalDateTime.now())
                        .build();
                images.add(image1);
            });
            imageMapper.addContentImages(images);
        }
    }

    @Override
    @Transactional
    public void deleteWork(Long wordId) {
        Work work = workMapper.getById(wordId);
        if (work == null){
            throw new RuntimeException(MessageConstant.WORK_IS_NULL);
        }

        //删除需求单的相关标签记录
        tagMapper.deleteByContentId(wordId,WORK);

        //删除需求单的相关图片记录
        imageMapper.deleteByWorkId(wordId);

        // 删除对应的缓存
        redisTemplate.delete("work" + wordId);
        //删除用户对该需求单的所有点赞
        likeMapper.deleteByDemandId(wordId,WORK);

        //删除用户删除收藏
        favoriteMapper.deleteByContentId(wordId,WORK);

        //删除用户对该需求单的浏览记录
        readMapper.deleteByItemId(wordId,WORK);

        //删除该需求单的所有评论
        commentMapper.deleteByItemId(wordId,WORK);

        //删除需求单本身
        workMapper.deleteById(wordId);
    }
}
